using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;

 

namespace BuildingStructuralElements.Sections

{
    //here is the basic Layer  for imporiting and using the 
    // functionallity  of _Section  Manager of  INSTANT .
    

    //DECLARING FUNCTIONS MSOFT terminology 
    public class CSection_Facade
    {
        #region "CSection Calling Functions Block"

        [DllImport("SectionDBEngine.dll", EntryPoint = "LoadCSectionFiles")]
        public static extern int LoadCSectionFiles();

        [DllImport("SectionDBEngine.dll", EntryPoint = "getHeadersByIndex")]
        public static extern int getHeadersByIndex([In, Out] CSectionHeader[] headers, int size);

        [DllImport("SectionDBEngine.dll", EntryPoint = "getDataStruct")]
        public static extern int getDataStruct(ref CSectionData data, int size, int i, int j);

        [DllImport("SectionDBEngine.dll", EntryPoint = "getHeaderStruct")]
        public static extern int getHeaderStruct(ref CSectionHeader header, int i);

        //[DllImport("SectionDBEngine.dll", EntryPoint = "getFileStruct")]
        //public static extern int getFileStruct(ref CSectionFile file, int i);

        [DllImport("SectionDBEngine.dll", EntryPoint = "getNumOfSectionsFiles")]
        public static extern int getNumOfSectionsFiles(ref int m_num_files);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestGetHeader")]
        public static extern int TestGetHeader(ref CSectionHeader header, int index);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestGetHeader")]
        public static extern int TestGetHeaders([In, Out] CSectionHeader[] headers);

        [DllImport("SectionDBEngine.dll", EntryPoint = "LoadCSectionFilesPath")]
        public static extern int LoadCSectionFilesPath(String path, int lang);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestGetNumOfProfileFields")]
        public static extern int TestGetNumOfProfileFields(ref int num_of_fields);

        [DllImport("SectionDBEngine.dll", EntryPoint = "getFields")]
        public static extern int getFields([In, Out] CSectionField[] headers, int fieldIndex);

        [DllImport("SectionDBEngine.dll", EntryPoint = "GetSectionDataStructAndIndex")]
        public static extern bool GetSectionDataStructAndIndex(String SectionName, ref CSectionData dataStruct
            , ref int header);

        #endregion

        #region "CSection CAlling Calculation Block"

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestCalculate_I_SectionData")]
        public static extern bool TestCalculate_I_SectionData(ref CSectionData data);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestCalculate_Rect_SectionData")]
        public static extern bool TestCalculate_Rect_SectionData(ref CSectionData data);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestCalculate_Circle_SectionData")]
        public static extern bool TestCalculate_Circle_SectionData(ref CSectionData data);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestCalculate_TBeam_SectionData")]
        public static extern bool TestCalculate_TBeam_SectionData(ref CSectionData data);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestCalculateWeldedSectionData")]
        public static extern bool TestCalculateWeldedSectionData(ref CSectionData data);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestCalculateCastelatedSectionData")]
        public static extern bool TestCalculateCastelatedSectionData(ref CSectionData data);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestTranslateUnitsFromMMtoCM")]
        public static extern bool TestTranslateUnitsFromMMtoCM(ref CSectionData data);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestGetSectionDataStruct")]
        public static extern bool TestGetSectionDataStruct(String SectionName, ref CSectionData dataStruct);

        [DllImport("SectionDBEngine.dll", EntryPoint = "TestOfProfilefields")]
        public static extern bool TestOfProfilefields([In, Out] CSectionField[] Fields, int profileIndex);

        #endregion
    }
 
    enum SEC_FIELDS
    {

        DTL_FIRST = 0,

        // General details 1-5
        SMANAGER_DTL_A = 0,
        SMANAGER_DTL_G,
        SMANAGER_DTL_AL,
        SMANAGER_DTL_AG,
        SMANAGER_DTL_GEOM_UNUSED1,

        // Geometric details 6-25
        SMANAGER_DTL_GEOMETRIC1 = 5,
        SMANAGER_DTL_GEOMETRIC2,
        SMANAGER_DTL_GEOMETRIC3,
        SMANAGER_DTL_GEOMETRIC4,
        SMANAGER_DTL_GEOMETRIC5,
        SMANAGER_DTL_GEOMETRIC6 = 10,
        SMANAGER_DTL_GEOMETRIC7,
        SMANAGER_DTL_GEOMETRIC8,
        SMANAGER_DTL_GEOMETRIC9,
        SMANAGER_DTL_GEOMETRIC10,
        SMANAGER_DTL_GEOMETRIC11 = 15,
        SMANAGER_DTL_GEOMETRIC12,
        SMANAGER_DTL_GEOMETRIC13,
        SMANAGER_DTL_GEOMETRIC14,
        SMANAGER_DTL_GEOMETRIC15,
        SMANAGER_DTL_GEOMETRIC16 = 20,
        SMANAGER_DTL_GEOMETRIC17,
        SMANAGER_DTL_GEOMETRIC18,
        SMANAGER_DTL_GEOMETRIC19,
        SMANAGER_DTL_GEOMETRIC20 = 24,

        // Inertia details about z axis: 26-35
        SMANAGER_DTL_IZ = 25,
        SMANAGER_DTL_WZ_PLUS,
        SMANAGER_DTL_WZ_MINUS,
        SMANAGER_DTL_WPLZ,
        SMANAGER_DTL_IIZ,
        SMANAGER_DTL_AVZ,
        SMANAGER_DTL_Z_UNUSED1,
        SMANAGER_DTL_Z_UNUSED2,
        SMANAGER_DTL_Z_UNUSED3,
        SMANAGER_DTL_Z_UNUSED4 = 34,

        // Inertia details about vv axis: 36-45
        SMANAGER_DTL_IV = 35,
        SMANAGER_DTL_WV_PLUS,
        SMANAGER_DTL_WV_MINUS,
        SMANAGER_DTL_WPLV,
        SMANAGER_DTL_IIV,
        SMANAGER_DTL_AVV,
        SMANAGER_DTL_V_UNUSED1,
        SMANAGER_DTL_V_UNUSED2,
        SMANAGER_DTL_V_UNUSED3,
        SMANAGER_DTL_V_UNUSED4 = 44,

        // Inertia details about y axis: 46-55
        SMANAGER_DTL_IY = 45,
        SMANAGER_DTL_WY_PLUS,
        SMANAGER_DTL_WY_MINUS,
        SMANAGER_DTL_WPLY,
        SMANAGER_DTL_IIY,
        SMANAGER_DTL_AVY,
        SMANAGER_DTL_Y_UNUSED1,
        SMANAGER_DTL_Y_UNUSED2,
        SMANAGER_DTL_Y_UNUSED3,
        SMANAGER_DTL_Y_UNUSED4 = 54,

        // Inertia details about uu axis: 56-65
        SMANAGER_DTL_IU = 55,
        SMANAGER_DTL_WU_PLUS,
        SMANAGER_DTL_WU_MINUS,
        SMANAGER_DTL_WPLU,
        SMANAGER_DTL_IIU,
        SMANAGER_DTL_AVU,
        SMANAGER_DTL_U_UNUSED1,
        SMANAGER_DTL_U_UNUSED2,
        SMANAGER_DTL_U_UNUSED3,
        SMANAGER_DTL_U_UNUSED4 = 64,

        // Other details : 66-100
        SMANAGER_DTL_J = 65,			// Torsional Constant
        SMANAGER_DTL_IW = 66,			// Warping Constant
        SMANAGER_DTL_ANGLE_A = 67,			// Angle between geom-principal axis
        SMANAGER_DTL_OTHER_UNUSED1 = 68,
        SMANAGER_DTL_OTHER_UNUSED2 = 69,

        DTL_LAST = 99,

    };
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct CSectionField
    {

        public String Name;
        public String Description;
        public int NumOfProfiles;
        public CSectionField(String name, String description)
        {
            this.Name = name;
            this.Description = description;
            this.NumOfProfiles = 0;
        }
    }

    public class CSectionFields
    {
        private CSectionField[] fields;

        public CSectionFields()
        {

            fields = new CSectionField[100];
        }

        public void getFields(int fileIndex)
        {
            if (fileIndex <= 0) return;



            for (int h = 0; h < 100; h++)
            {
                fields[h].Description = "";
                fields[h].Name = "";
            }


            try
            {

                int namesSum = CSection_Facade.getFields(fields, fileIndex);
            }
            catch (Exception exp)
            {
                throw (new SectionDllException("Fields cannot be loaded."));
            }

        }


        public CSectionField[] Fields
        {
            get { return this.fields; }
            set { this.fields = value; }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct CSectionData
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
        public double[] m_Data;
        public String Name;

        public double A() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_A]; }
        public double G() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_G]; }

        public double AL() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AL]; }
        public double AG() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AG]; }

        public double J() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_J]; }
        public double Iw() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IW]; }

        public double Iz() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IZ]; }
        public double Wzplus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WZ_PLUS]; }
        public double Wzminus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WZ_MINUS]; }
        public double Wplz() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLZ]; }
        public double iz() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIZ]; }
        public double Avz() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVZ]; }

        public double Iv() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IV]; }
        public double Wvplus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WV_PLUS]; }
        public double Wvminus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WV_MINUS]; }
        public double Wplv() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLV]; }
        public double iv() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIV]; }
        public double Avv() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVV]; }

        public double Iy() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IY]; }
        public double Wyplus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WY_PLUS]; }
        public double Wyminus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WY_MINUS]; }
        public double Wply() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLY]; }
        public double iy() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIY]; }
        public double Avy() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVY]; }

        public double Iu() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IU]; }
        public double Wuplus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WU_PLUS]; }
        public double Wuminus() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WU_MINUS]; }
        public double Wplu() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLU]; }
        public double iu() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIU]; }
        public double Avu() { return m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVU]; }

        public void A(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_A] = val; }
        public void G(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_G] = val; }
        public void AL(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AL] = val; }
        public void AG(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AG] = val; }

        public void J(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_J] = val; }
        public void Iw(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IW] = val; }

        public void Iz(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IZ] = val; }
        public void Wzplus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WZ_PLUS] = val; }
        public void Wzminus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WZ_MINUS] = val; }
        public void Wplz(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLZ] = val; }
        public void iz(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIZ] = val; }
        public void Avz(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVZ] = val; }

        public void Iv(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IV] = val; }
        public void Wvplus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WV_PLUS] = val; }
        public void Wvminus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WV_MINUS] = val; }
        public void Wplv(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLV] = val; }
        public void iv(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIV] = val; }
        public void Avv(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVV] = val; }

        public void Iy(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IY] = val; }
        public void Wyplus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WY_PLUS] = val; }
        public void Wyminus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WY_MINUS] = val; }
        public void Wply(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLY] = val; }
        public void iy(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIY] = val; }
        public void Avy(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVY] = val; }

        public void Iu(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IU] = val; }
        public void Wuplus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WU_PLUS] = val; }
        public void Wuminus(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WU_MINUS] = val; }
        public void Wplu(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_WPLU] = val; }
        public void iu(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_IIU] = val; }
        public void Avu(double val) { m_Data[(int)SEC_FIELDS.SMANAGER_DTL_AVU] = val; }

    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct CSectionHeader
    {
        public String Name;
        public String Description;
        public int NumOfProfiles;
        public int profileIndex;

        public CSectionHeader(String name, String description)
        {
            this.Name = name;
            this.Description = description;
            this.NumOfProfiles = 0;
            this.profileIndex = 0;
        }

    }

    public abstract class AbstractSectionManagerINSTANT : ISectionManager
    {
        public abstract void LoadHeaders();
        public abstract Section LoadSection(string name);
        public abstract void LoadSection(int profileIndex, int fileIndex);
        public abstract void LoadSectionFile();
        public abstract void LoadSectionFile(string path);
        public abstract void LoadSectionsNames(int profile);
        public abstract string Path { get; set; }
        public abstract Section _Section { get; }
        public abstract string[] SectionsNames { get; }
        public abstract string[] HeaderNames { get; }

        #region ISectionManager Members

        public abstract  bool ExistSection(string type, string name);

        public abstract  List<string> GetListOfSectionsNames();

        public abstract double GetSectionInertiaAttribute(string table, string name, string attribute);

        #endregion
    }

    public class SectionDllException : Exception
    {
        public SectionDllException(string message): base(message)
        {
            //this.ErrorMessage = message;

        }
        public SectionDllException(string message, Exception inner) : base(message, inner) { }
        public SectionDllException() : base() { }
        public override string Message
        {
            get
            {
                return base.Message;
            }
        }
    }

}
